
package de.justphil.tcg.tcgandroidclient.network.rest;

import java.util.Collection;
import java.util.HashSet;

import de.justphil.tcg.tcgandroidclient.Storage;
import de.justphil.tcg.tcgandroidclient.content.DH;
import de.justphil.tcg.tcgandroidclient.content.TCGContentAdapter;
import de.justphil.tcg.tcgandroidclient.content.TCGUM;
import de.justphil.tcg.tcgandroidclient.network.rest.Http.Method;
import de.justphil.tcg.tcgandroidclient.util.StringTools;
import de.justphil.tcg.tcgandroidclient.util.TCGLog;
import android.app.IntentService;
import android.content.Intent;
import android.net.Uri;

public class RESTUpdateService extends IntentService {
	
	public static final int RQ_PROPERTY_IMG = 1;
	public static final int RQ_CARD_IMG = 2;
	public static final int RQ_CARD_VALUES = 3;
	public static String EXTRA_CLEAR_CACHE = "clear";
	private TCGContentAdapter caUseGetter = null;
	private static final Collection<String> cache = new HashSet<String>();
	
	public RESTUpdateService() {
	
		super("RESTUpdateService");
	}
	
	@Override
	public void onDestroy() {
	
		super.onDestroy();
		TCGLog.i(new Object[] {
			"Destroying the RESTUpdateService." });
	}
	
	public TCGContentAdapter getContentAdapter() {
	
		if (caUseGetter == null) {
			caUseGetter = new TCGContentAdapter(this);
		}
		return caUseGetter;
	}
	
	@Override
	protected void onHandleIntent(Intent intent) {
	
		if (intent.getBooleanExtra(EXTRA_CLEAR_CACHE, false)) {
			clearCache();
		}
		Uri uri = intent.getData();
		if (uri == null) {
			return;
		}
		/* Combining Uris and checking cache. */
		switch (DH.UM.match(uri)) {
			case TCGUM.URI_CARD:
				break;
			case TCGUM.URI_CARD_IMG:
				break;
			case TCGUM.URI_CARD_TO_PROPERTIES:
				uri = TCGUM.getCardUri(TCGUM.getIntId(0, uri));
				break;
			case TCGUM.URI_CARD_INSTANCE:
				uri = TCGUM.getCardInstancesUri(Storage.getPlayerId());
				break;
			case TCGUM.URI_CARD_INSTANCES:
				break;
			case TCGUM.URI_PROPERTY_IMG:
				break;
			case TCGUM.URI_DECK_TO_CARDS:
			case TCGUM.URI_DECK:
				uri = TCGUM.getDecksUri(Storage.getPlayerId());
				break;
			case TCGUM.URI_DECKS:
				break;
			default:
				throw new IllegalArgumentException("The uri " + uri + " could not be recognized!");
		}
		if (!cache.contains(uri.toString())) {
			TCGLog.i(new Object[] {
					"REST requesting Uri: ", uri });
			ResponseContainer rc = RESTHelper.restRequest(this, getUrl(uri), null, Method.GET);
			TCGLog.v(new Object[] {
				"Cached:" });
			for (String uriStr : cache) {
				TCGLog.v(new Object[] {
					uriStr });
			}
			if (rc == null) {
				TCGLog.w(new Object[] {
					"REST request returned without result!" });
			}
			else if (rc.getResponseCode() == RESTHelper.CODE_OK) {
				switch (DH.UM.match(uri)) {
					case TCGUM.URI_CARD: {
						int cardType = TCGUM.getIntId(0, uri);
						getContentAdapter().writeCard(cardType,
								RESTDecoder.decodeCard(RESTHelper.getBodyStr(rc)));
						break;
					}
					case TCGUM.URI_CARD_IMG: {
						int cardType = TCGUM.getIntId(0, uri);
						getContentAdapter().writeCardImg(cardType, rc.getBytes());
						break;
					}
					case TCGUM.URI_PROPERTY_IMG: {
						int cardType = TCGUM.getIntId(0, uri);
						getContentAdapter().writePropertyImg(cardType, rc.getBytes());
						break;
					}
					case TCGUM.URI_DECKS: {
						getContentAdapter().writeDecks(
								RESTDecoder.decodeDecks(RESTHelper.getBodyStr(rc)));
						break;
					}
					case TCGUM.URI_CARD_INSTANCES: {
						getContentAdapter().writeCardInstances(
								RESTDecoder.decodeCardInstances(RESTHelper.getBodyStr(rc)));
						break;
					}
					default:
						throw new IllegalArgumentException("The uri " + uri
								+ " could not be recognized!");
				}
			}
			else {
				TCGLog.e(new Object[] {
						"REST server did not return 200 OK\n", "Uri '", uri, "'\n", "Url '",
						getUrl(uri), "'\n", "Response Code: ", rc.getResponseCode() });
			}
			/* caching */
			TCGLog.i(new Object[] {
					"Caching Uri '", uri, "'." });
			cache.add(uri.toString());
		}
		else {
			TCGLog.d(new Object[] {
					"REST Already requested Uri: ", uri });
		}
		return;
	}
	
	private void clearCache() {
	
		TCGLog.i(new Object[] {
			"REST Clearing uri cache." });
		cache.clear();
	}
	
	private String getUrl(Uri uri) {
	
		String url = null;
		switch (DH.UM.match(uri)) {
			case TCGUM.URI_CARD: {
				int cardType = TCGUM.getIntId(0, uri);
				url = StringTools.getString(new Object[] {
						"/card/", cardType });
				break;
			}
			case TCGUM.URI_CARD_IMG: {
				int cardType = TCGUM.getIntId(0, uri);
				url = StringTools.getString(new Object[] {
						"/card/", cardType, "/image" });
				break;
			}
			case TCGUM.URI_PROPERTY_IMG: {
				int propertyType = TCGUM.getIntId(0, uri);
				url = StringTools.getString(new Object[] {
						"/property/", propertyType, "/image" });
				break;
			}
			case TCGUM.URI_DECKS: {
				long userId = TCGUM.getLongId(0, uri);
				url = StringTools.getString(new Object[] {
						"/user/", userId, "/decks" });
				break;
			}
			case TCGUM.URI_CARD_INSTANCES: {
				long userId = TCGUM.getLongId(0, uri);
				url = StringTools.getString(new Object[] {
						"/user/", userId, "/cards" });
				break;
			}
			default:
				throw new IllegalArgumentException("The uri " + uri
						+ " could not be converted to a REST url!");
		}
		return url;
	}
}
